package model.entity.stats;

import java.util.List;
import java.util.ArrayList;

import model.Model;
import utilities.*;

public class Stat extends Model implements Archiveable {
	// Instance Variables
	private double baseValue;
	private List<StatModifier> modifiers;
	
	
	// Constructor
	/**
	 * Default constructor
	 */
	public Stat() 
	{
		this(0.0, "Default");
	}
	
	/**
	 * Constructor: sets base value and creates modifiers array
	 * @param base
	 */
	public Stat(double base, String statType) {
		super(statType);
		this.baseValue = base;
		this.modifiers = new ArrayList<StatModifier>();
	}
	
	
	// Getters
	/**
	 * Iterates through each stat modifier, adding(/subtracting) its value
	 */
	public double getValue() {
		// Start with base value
		double value = this.baseValue;
		
		// For each stat modifier, add(/subtract) its getValue() value
		for (StatModifier m : this.modifiers) {
			value += m.getValue(this.baseValue);
		}
		
		return value;
	}
	
	/**
	 * 
	 * @return the base value
	 */
	public double getBaseValue() {
		return this.baseValue;
	}
	
	public void addToBaseValue(double val)
	{
		baseValue+=val;
	}
	
	
	// Stat Modifiers
	/**
	 * Returns the stat modifier for the specified name, null otherwise
	 */
	public StatModifier getStatModifier(String key) {
		for (StatModifier m : this.modifiers) {
			if (m.getName() == key) {
				return m;
			}
		}
		return null;
	}
	
	/**
	 * Adds the modifier to the list
	 * @param modifier
	 */
	public void addStatModifier(StatModifier modifier) {
		this.modifiers.add(modifier);
	}
	
	/**
	 * Removes the specified modifier from the list, and returns it
	 * @param key
	 * @return the removed modifier, or null if there is not a modifier for
	 * the specified name
	 */
	public StatModifier removeStatModifier(String key) {
		StatModifier modifier = null;
		for (StatModifier m : this.modifiers) {
			if (m.getName() == key) {
				modifier = m;
				break;
			}
		}
		return modifier;
	}
	/* (non-Javadoc)
	 * @see model.Model#toString()
	 */
	public String toString() {
		return super.toString() + ": " + this.baseValue;
	}
	
	public Archive save() {
		Archive archive = super.save();
		
		archive.putAttribute("baseValue", Double.toString(this.baseValue));
		
		List<String> modifiersClassList = new ArrayList<String>(this.modifiers.size());
		for (StatModifier modifier : this.modifiers) {
			modifiersClassList.add(modifier.getClass().getName());
		}
		archive.putAttributeList("modifiersClassList", modifiersClassList);
		archive.putManyRelationship("modifiers", this.modifiers);
		
		return archive;
	}
	
	public void load(Archive archive) {
		super.load(archive);
		
		this.baseValue = Double.parseDouble(archive.getAttribute("baseValue"));
		
		List<String> modifiersClassList = archive.getAttributeList("modifiersClassList");
		List<Archive> modifiersArchives = archive.getManyRelationship("modifiers");
		this.modifiers = new ArrayList<StatModifier>();
		for (int i = 0; i < modifiersClassList.size(); i++) {
			StatModifier modifier = (StatModifier)ModelFactory.getInstance().createInstanceWithClassName(modifiersClassList.get(i));
			modifier.load(modifiersArchives.get(i));
			
			this.modifiers.add(modifier);
		}
	}
	
}
